<template>
  <view class="image-preview-wrapper" @click.stop="handleClick">
    <image
      :src="src"
      :mode="mode"
      :style="imageStyle"
      class="preview-image"
      @load="handleImageLoad"
      @error="handleImageError"
    ></image>
    <slot></slot>
  </view>
</template>

<script setup>
import { ref, computed } from "vue";

// 组件属性
const props = defineProps({
  // 图片地址
  src: {
    type: String,
    required: true,
  },
  // 图片裁剪、缩放模式
  mode: {
    type: String,
    default: "aspectFill", // widthFix, aspectFit, aspectFill
  },
  // 自定义样式
  customStyle: {
    type: String,
    default: "",
  },
  // 图片宽度
  width: {
    type: [String, Number],
    default: "100%",
  },
  // 图片高度
  height: {
    type: [String, Number],
    default: "auto",
  },
  // 是否开启预览
  preview: {
    type: Boolean,
    default: true,
  },
  // 预览组的图片列表
  previewList: {
    type: Array,
    default: () => [],
  },
});

// 图片加载状态
const isLoaded = ref(false);
const hasError = ref(false);

// 计算样式
const imageStyle = computed(() => {
  let style = `width: ${
    typeof props.width === "number" ? props.width + "rpx" : props.width
  };`;
  style += `height: ${
    typeof props.height === "number" ? props.height + "rpx" : props.height
  };`;
  if (props.customStyle) style += props.customStyle;
  return style;
});

// 处理图片点击
const handleClick = () => {
  if (!props.preview || hasError.value) return;

  // 如果有预览列表，使用列表，否则只预览当前图片
  const urls = props.previewList.length > 0 ? props.previewList : [props.src];

  const current =
    props.previewList.length > 0 ? props.previewList.indexOf(props.src) : 0;

  // 使用uni-app的图片预览API
  uni.previewImage({
    urls: urls,
    current: current,
    indicator: "number",
    loop: true,
    fail: (err) => {
      console.error("图片预览失败:", err);
    },
  });
};

// 图片加载完成
const handleImageLoad = (e) => {
  isLoaded.value = true;
};

// 图片加载失败
const handleImageError = (e) => {
  hasError.value = true;
  console.error("图片加载失败:", props.src);
};
</script>

<style>
.image-preview-wrapper {
  position: relative;
  display: inline-block;
  overflow: hidden;
}

.preview-image {
  display: block;
}
</style>
